#pragma once

#include "iterator.h"

namespace sfc::iter {

template <class I, class P>
struct Filter {
  using Item = typename I::Item;

  I _iter;
  P _pred;

 public:
  [[sfc_inline]] auto next() -> option::Option<Item> {
    return _iter->find(_pred);
  }

  [[sfc_inline]] auto next_back() -> option::Option<Item> {
    return _iter->rfind(_pred);
  }

  [[sfc_inline]] auto operator->() -> Iter<Filter> {
    return static_cast<Iter<Filter>*>(this);
  }
};

template <class I, class P>
Filter(I, P) -> Filter<I, P>;

template <class I>
auto Iter<I>::filter(auto f) {
  return Filter{static_cast<I&&>(*this), static_cast<decltype(f)&&>(f)};
}

}  // namespace sfc::iter
